package com.hejing.反射的理解与使用;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * ClassName: ReflectionTest
 * Package: com.hejing.反射的理解与使用.txt
 * Description:
 *
 * @Author: HeJing
 * @Create: 2023-06-03 16:07
 * @Version: 1.0
 */
public class ReflectionTest {
    /**
     * 使用反射之前可以执行的操作
     */
    @Test
    public void test01(){

        // 1、创建Person类的实例
        Person p1 = new Person();

        // 2、调用属性
        p1.age = 10;
        System.out.println(p1.age);

        // 3、调用方法
        p1.show();
    }

    /**
     * 使用反射完成test1中的操作。
     */
    @Test
    public void test02() throws InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {

        // 1、创建Person类的实例
        Class clazz = Person.class;
        Person p1 = (Person) clazz.newInstance();  // 仅限于调用空参构造器
        System.out.println(p1);

        // 2、调用属性
        Field ageField = clazz.getField("age");
        ageField.set(p1, 10);
        System.out.println(ageField.get(p1));

        // 3、调用方法:
        Method showMethod = clazz.getMethod("show");
        showMethod.invoke(p1);

    }

    /**
     * 出了Person类之后，就不能直接调用Person类中声明的private权限修饰的结构(属性、方法、构造器)
     * 但是，我们可以通过反射的方式调用Person类中私有的结构。
     */
    @Test
    public void test03() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {

        // 1、调用私有的构造器，创建Person实例
        Class clazz = Person.class;
        Constructor cons = clazz.getDeclaredConstructor(String.class, int.class);
        cons.setAccessible(true);

        Person p1 = (Person)cons.newInstance("Tom", 12);
        System.out.println(p1);


        // 2、调用私有的属性
        Field nameField = clazz.getDeclaredField("name");
        nameField.setAccessible(true);
        nameField.set(p1, "Jerry");
        System.out.println(nameField.get(p1));

        // 3、调用私有的方法
        Method showNationMethod = clazz.getDeclaredMethod("showNation", String.class);
        showNationMethod.setAccessible(true);
        String info = (String) showNationMethod.invoke(p1, "CHN");
        System.out.println(info);
    }
}






























